package cn.wx.config;

import cn.wx.dto.Result;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 对前端响应结果统一封装
 */
@Slf4j
@RestControllerAdvice(basePackages = { "cn.wx" })
public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
    /**
     * 打印统一请求响应规范
     */
    ApiResponseAdvice() {
        log.info("启动请求统一响应规范... ...");
    }

    /**
     * 判断是否需要对返回值进行封装
     * @param returnType the return type
     * @param converterType the selected converter type
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 如果返回的结果是Result.class类型就不用封装
        if (returnType.getParameterType().equals(Result.class)) {
            return false;
        }
        return true;
    }

    /**
     * 对返回前端的值统一封装
     * @param body the body to be written
     * @param returnType the return type of the controller method
     * @param selectedContentType the content type selected through content negotiation
     * @param selectedConverterType the converter type selected to write to the response
     * @param request the current request
     * @param response the current response
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body,
            MethodParameter returnType,
            MediaType selectedContentType,
            Class<? extends HttpMessageConverter<?>> selectedConverterType,
            ServerHttpRequest request,
            ServerHttpResponse response) {
        if (returnType.getParameterType().equals(String.class)) {
            // 如果是String类需要特殊处理
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 设置响应数据格式为json
                response.getHeaders().add("content-type", "application/json;charset=UTF-8");
                return objectMapper.writeValueAsString(Result.success(body));
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return Result.success(body);
    }
}